//
//  DiscoveryController.swift
//  发现页面
//
//  Created by smile on 2019/4/10.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

//导入数据库框架
import RealmSwift

//主题框架
import SwiftTheme

//发布订阅框架
import SwiftEventBus

//日志框架
import CocoaLumberjack

class DiscoveryController: BaseMusicPlayerController,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
    
    //日志TAG
    private static let TAG="DiscoveryController"
    
    @IBOutlet weak var btMicrophone: UIBarButtonItem!
    
    /// 搜索按钮
    @IBOutlet weak var btSearch: UIButton!
    
    /// 当前界面头部布局
    var header:DiscoveryHeaderView!
    
    /// 用来存储轮播图对象
    var bannerArray:[Ad]=[]
    
    /// 当前界面列表数据
    var dataArray:[Any]=[]
    
    /// 热门搜索数据
    var popularSearchArray:[String] = []
    
    var searchViewController:PYSearchViewController!
    
    /// 异步任务
    var task:DispatchWorkItem?

    override func initViews() {
        super.initViews()
        
        DDLogWarn("DiscoveryController initViews")
        
        DDLogWarn("initViews",tag: DiscoveryController.TAG)
        DDLogWarn("initViews",tag: DiscoveryController.TAG)
        
        //主题配置
        
        //背景
        //白天显示白色
        //夜间显示深黑色
        view.theme_backgroundColor=[COLOR_STRING_WHITE, COLOR_STRING_DARK_BLACK]
       
       //导航栏字体颜色
        //白天为默认；也就是文字显示黑色
        //夜间为黑色(说的是倍背景)；也就是文字显示白色
        navigationController!.navigationBar.theme_barStyle=ThemeBarStylePicker(styles: .default, .black)
        
        //导航栏颜色文字颜色
        //指的是文字标题那部分
        //由于发现页面没有标题所以不用设置
//        navigationController!.navigationBar.theme_barTintColor=["#000","#999"]
        
        //麦克风图标
        btMicrophone.theme_tintColor=[COLOR_STRING_BLACK,COLOR_STRING_LIGHT_GREY]
        
        //搜索按钮
        btSearch.theme_backgroundColor=[COLOR_STRING_GROUP_TABLE_VIEW_BACKGROUND, COLOR_STRING_SEARCH_BACKGROUND]
        
        
//        设置搜索按钮圆角半径
        ViewUtil.showRadius(btSearch, 15)
    
        //注册头部
        collectionView.register(UINib(nibName: DiscoveryHeaderView.NAME, bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DiscoveryHeaderView.NAME)
        
        //创建一个Nib
        let titleCell=UINib(nibName: TitleCell.NAME, bundle: nil)
        
        //注册标题Cell
        //注册后，collectionView才能显示
        self.collectionView.register(titleCell, forCellWithReuseIdentifier: TitleCell.NAME)
        
        //注册歌单Cell
        self.collectionView.register(UINib(nibName: SheetCell.NAME, bundle: nil), forCellWithReuseIdentifier: SheetCell.NAME)
        
        //注册单曲Cell
        collectionView.register(UINib(nibName: SongCell.NAME, bundle: nil), forCellWithReuseIdentifier: SongCell.NAME)
        
        //添加右上角按钮
        navigationItem.rightBarButtonItem=createPlayingBar()
        
        //测试获取状态栏高度
        //获取的值是一倍尺寸
        let statusRect = UIApplication.shared.statusBarFrame
        print("DiscoveryController status rect:\(statusRect)")
        
        //测试获取导航栏高度
        let navigationRect = self.navigationController?.navigationBar.frame;
        print("DiscoveryController navigation rect:\(navigationRect)")
        
        
    }
    
    override func initDatas() {
        super.initDatas()
        
        DDLogWarn("DiscoveryController initDatas")
        
        DDLogWarn("initDatas",tag: DiscoveryController.TAG)
        
        fetchBanner()
        fetchData()
        
        fetchPopularSearch()
        
        //测试数据库使用
        //创建一个对象
//        let person=Person()
//        
//        //赋值
//        person.name="ixuea"
//        person.age=10
//
//        //创建数据库框架
//        let realm = try! Realm()
//
//        try! realm.write {
//            //保存人
//            realm.add(person)
//        }
//
//        //查询所有人
//        let persons = realm.objects(Person.self)
//
//        //打印出有多个人
//        print("count:\(persons.count)")
//
//        //获取当前应用沙盒路径
//        var path=NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
//
//        print("document path:\(path)")
    }
    
    /// 已经重新布局
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

//        let frame = btSearch.frame
//
//        btSearch.frame=CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.width-100, height: frame.size.height)
        
        //获取布局的安全区
        //在该界面iPhone X上
        //top是88：是状态栏+到导航栏的高度
        //bottom是83：49（TabBar高度）+34（底部安全区）
        //获取使用代码布局的时候可以手动偏移这么多距离
        //当然也可以使用自动布局和safeAreaInsets对齐
        let safeAreaInsets=view.safeAreaInsets
        print("DiscoveryController safe area insets:\(safeAreaInsets)")
    }

    /// 获取搜索建议
    ///
    /// - Parameter searchText: <#searchText description#>
    func fetchSuggestion(_ searchText:String) {
        Api.shared
            .searcheSuggests(searchText)
            .subscribeOnSuccess { (data) in
                if let data = data?.data {
                    var suggestions:[String]=[]
                    
                    if data.sheets.count > 0 {
                        //有歌单搜索建议
                        //获取字符串
                        //因为搜索框架是需要字符串
                        suggestions=suggestions+data.sheets.map({ (searchTitle) -> String in
                            searchTitle.title
                        })
                    }
                    
                    if data.users.count > 0 {
                        //有歌单搜索建议
                        //获取字符串
                        //因为搜索框架是需要字符串
                        suggestions=suggestions+data.users.map({ (searchTitle) -> String in
                            searchTitle.title
                        })
                    }
                    
                    //设置到搜索控制器
                    self.searchViewController.searchSuggestions=suggestions
                }
        }.disposed(by: disposeBag)
    }
    
    /// 尝试获取搜索建议
    /// 该方法功能是对搜索建议API进行限流
    /// 这部分代码可以封装
    ///
    /// - Parameter searchText: <#searchText description#>
    func tryFetchSuggestion(_ searchText:String) {
        cancelTask()
        
        //如果要取消异步任务就需要这样使用
        //创建一个任务
        task = DispatchWorkItem {
            //这里是异步任务执行时回调
            self.fetchSuggestion(searchText)
        }
        
        //300毫秒后获取搜索建议
        //添加到异步队列中
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(300), execute: task!)
    }
    
    /// 取消任务
    func cancelTask() {
        if let task = task {
            task.cancel()
        }
        
        task=nil
    }
    
    /// 请求热门搜索
    func fetchPopularSearch() {
        //添加测试数据
        //因为服务端没有实现热门搜索功能
        for i in 0..<10 {
            popularSearchArray.append("热门搜索\(i)")
        }
 
    }
    
    /// 请求轮播图数据
    func fetchBanner() {
        Api.shared
            .ads()
            .subscribeOnSuccess { data in
                //因为有可能没有广告数据
                //所有这样要判断
                if let data = data?.data {
                    self.showBannerData(data)
                }
                
            }.disposed(by: disposeBag)
        
    }
    
    
    /// 加载首页数据
    func fetchData() {
        //先添加一些测试数据
//        dataArray.append("这是标题1")
//        for i in 1...10 {
//            let sheet=Sheet()
//            sheet.title="这是歌单\(i)，标题很长长长长长长长长长长长长长长长长"
//            dataArray.append(sheet)
//        }
//        dataArray.append("这是标题8")
        
        //清除原来的数据
        dataArray.removeAll()
        
        //这里实现的是三个接口的数据放到一个列表中
        //而且有先后顺序
        //现在的实现是，嵌套调用
        //如果大家熟悉响应式编程，可以改进
        //也可以使用多线程请求
        //然后按照一定的顺序添加到列表
        
        //歌单列表
        Api.shared
            .sheets()
            .subscribeOnSuccess { data in
            if let data = data?.data {
                //添加标题
                self.dataArray.append("推荐歌单")
                
                //添加真实的数据
                self.dataArray=self.dataArray+data
   
                //请求单曲列表
                Api.shared.songs().subscribeOnSuccess({ data in
                    if let data = data?.data {
                        //添加标题
                        self.dataArray.append("推荐单曲")
                        
                        //添加真实的数据
                        self.dataArray=self.dataArray+data
                        
                        //通知CollectionView刷新数据
                        self.collectionView.reloadData()
                    }
                    
                }).disposed(by: self.disposeBag)
                
            }
        }.disposed(by: disposeBag)
        
    }
    
    func showBannerData(_ data:[Ad]) {
        //保存到当前界面的数组中
        bannerArray=bannerArray+data
        
        //将数据设置到头部控件中
        self.header.bindData(bannerArray)
    }
    
    override func initListeners() {
        super.initListeners()
        
        
        //添加一个通知监听器
        //当用户点击了启动界面的广告
        //就会在onAdClick方法中接收到
      NotificationCenter.default.addObserver(self, selector: #selector(onAdClick(notification:)), name: NSNotification.Name(rawValue: AD_CLICK), object: nil)

    }
    
    
    /// 当启动界面点击了广告回调
    ///
    /// - Parameter notification: <#notification description#>
    @objc func onAdClick(notification:NSNotification) {
        let uri=notification.userInfo!["uri"] as! String
        print("DiscoveryController onAdClick:\(uri)")
        
        //使用WebView控制器显示广告页面
        //创建控制器
//        let controller=navigationController!.storyboard?.instantiateViewController(withIdentifier: "Web") as! WebController
//
//        //将传递过来的数据设置到controller中
//        controller.title="活动详情"
//        controller.uri=uri
//
//        //将控制器压入导航控制中
//        navigationController!.pushViewController(controller, animated: true)
        
       //使用重构后的方法
        WebController.start(self.navigationController!, "活动详情", uri)
    }
    
    // MARK:- CollectionView相关方法
    /// 返回有多个条目
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataArray.count
    }
    
    /// 返回当前位置的Cell
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - indexPath: 当前位置
    /// - Returns: 返回当前位置对应的Cell
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        
        //取出当前位置对应的数据
        let data=dataArray[indexPath.row]
        
        //获取当前对象的类型
        let type=typeForItemAtData(data)
        
        switch type {
        case .Sheet:
            //歌单
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SheetCell.NAME, for: indexPath) as! SheetCell
            
            //绑定数据到这里
            cell.bindData(data as! Sheet)
            
            //返回给collectionView
            return cell
        case .Song:
            //单曲
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SongCell.NAME, for: indexPath) as! SongCell
            
            //绑定数据到这里
            cell.bindData(data as! Song)
            
            //返回给collectionView
            return cell
            
        default:
            //标题
            //从collectionView中去一个Cell
            //名字是TitleCell
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TitleCell.NAME, for: indexPath) as! TitleCell
            
            //绑定数据到这里
            cell.bindData(data as! String)
            
            //返回给collectionView
            return cell
        }
    }
    
    /// 获取列表类型
    ///
    /// - Parameter data: <#data description#>
    /// - Returns: <#return value description#>
    func typeForItemAtData(_ data:Any) -> CellType {
        
         if data is Sheet{
            //歌单
            return .Sheet
        } else if data is Song {
            //单曲
            return .Song
        }
        
        return .Title
    }
    
    
    /// Item点击事件
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - indexPath: <#indexPath description#>
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        //取出当前位置对应的数据
        let data=dataArray[indexPath.row]
        
        //获取当前对象的类型
        let type=typeForItemAtData(data)
        
        print("DiscoveryController didSelectItemAt:\(indexPath.row)")
        
        switch type {
        case .Sheet:
            //跳转到歌单详情
            let data=data as! Sheet
            SheetDetailController.start(self.navigationController!, data.id)
        case .Song:
            //跳转到播放界面
            let data=data as! Song
            playListManager.setPlayList([data])
            playListManager.play(data)
            pushMusicPlayerController()
            break
            
        default:
            break
        }
    }
    
    // MARK:- UICollectionViewDelegateFlowLayout代理相关方法
    /// 返回CollectionView与他的父View的间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        
//        return UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
    
    
    /// 返回每个Cell的行间距
    /// 也就是每行之间的间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return SIZE_LARGE_DIVIDER
    }
    
    
    /// 返回每个Cell的列间距
    /// 也就是每列之间的间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return SIZE_LARGE_DIVIDER
    }
    
    
    /// 返回当前Cell的大小
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        //获取到CollectionView的宽
        let collectionViewWidth=self.collectionView.frame.width
        
        //除以3，因为要显示3列
        //每列就是总宽度/3
//        let width=collectionViewWidth/3
        
        //10：是每列边距
        //*2：是因为显示3列，其实只有两个边距
        
        //取出当前位置对应的数据
        let data=dataArray[indexPath.row]
        
        //根据类型计算宽高
        var width:CGFloat!
        var height:CGFloat!
        
        //获取当前对象的类型
        let type=typeForItemAtData(data)
        
        switch type {
        case .Sheet:
            //歌单显示3列
            width=(collectionViewWidth-SIZE_LARGE_DIVIDER*2)/3
            
            //高度先+200，后面布局完成后在精确计算
//            height=width+200
            
            //计算高度
            height=width+SIZE_LARGE_DIVIDER+SIZE_TITLE_HEIGHT+SIZE_LARGE_DIVIDER
        case .Song:
            //歌曲显示正行
            width=collectionViewWidth
            
            //10+110（图片高度）+10
            height=130
        default:
            //标题显示整行
            width=collectionViewWidth
            height=SIZE_TITLE_HEIGHT
        }
        
        return CGSize(width: width, height: height)
    }

    
    /// 返回CollectionView的header
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - kind: <#kind description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        //将header中的内容都封装到单独的View中
        //好处是当前界面简洁一些
        //但坏处是头部的点击事件，需要通过一些方法
        //才能回调到当前界面
        header=collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DiscoveryHeaderView.NAME, for: indexPath) as! DiscoveryHeaderView
        
        //设置轮播图点击回调方法（类似OC中的block）
        header.onBannerClick={
            position in
            print("discovery controller onBannerClick:\(position)")
            
            let data=self.bannerArray[position]
            
            //启动Web页面
            WebController.start(self.navigationController!, data.title, data.uri)
        }

        return header
    }
    
    
    /// 返回header大小
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        
        //获取到CollectionView的宽
        let collectionViewWidth=self.collectionView.frame.width
        
        return CGSize(width: collectionViewWidth, height: SIZE_DISCOVERY_HEADER_HEIGHT)
    }
    
    
    
    /// 列表控件
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        
    }
    
    // MARK: - 导航栏事件
    /// 左侧麦克风点击事件
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onMicrophoneClick(_ sender: UIBarButtonItem) {
        print("DiscoveryController onMicrophoneClick")
    }
    
    /// 搜索按钮点击事件
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onSearchClick(_ sender: UIButton) {
        print("DiscoveryController onSearchClick")
        //创建搜索控制器
        searchViewController = PYSearchViewController(hotSearches: popularSearchArray, searchBarPlaceholder: "请输入你想搜索的内容.")!
        
        //设置代理
        searchViewController.delegate = self
        
        //设置搜索结果控制器显示模式
        //嵌入到当前界面
        searchViewController.searchResultShowMode = .embed
        
        //设置搜索结果显示控制器
        searchViewController.searchResultController = searchResultController
        
        //创建导航控制器
        let nav = UINavigationController(rootViewController: searchViewController)
        
        //显示控制器
        present(nav, animated: true, completion: nil)
    }
    
    /// 搜索结果控制器
    /// 懒加载
    lazy var searchResultController: UIViewController = {
        print("get searchResultController")
//        return self.storyboard!.instantiateViewController(withIdentifier: "SearchResult")
        
        return SearchResultController.init()
    }()
    
    /// 视图即将可见
    ///
    /// - Parameter animated: <#animated description#>
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //主题
        
        //状态栏
//        UIApplication.shared.theme_setStatusBarStyle(ThemeStatusBarStylePicker(styles: .default, .lightContent), animated: true)
        
        //设置导航栏样式
        //这里将导航栏背景设置为黑色
        //这样状态栏（有了导航栏，只能通过这种方式设置状态栏颜色）
        //标题就会变成白色
        //        navigationController!.navigationBar.barStyle=UIBarStyle.black
        
        //设置标题字体颜色
        //        navigationController!.navigationBar.titleTextAttributes=[.foregroundColor:UIColor.white]
        
        
        //设置返回按钮为白色
        //        navigationController!.navigationBar.tintColor=UIColor.white
        
        
        //导航栏透明
        //这里设置导航透明后，就没有上面的黑色了
        navigationController!.navigationBar.setBackgroundImage(UIImage(), for: .default)
        
        //去掉导航栏下面的阴影
        //如果大家需要可以留着
        //这个导航栏有层次感
        navigationController?.navigationBar.shadowImage=UIImage()
        
    }
    
    /// 视图即将消失
    ///
    /// - Parameter animated: animated description
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        //恢复状态栏颜色
        //因为其他界面可能当前界面样式不一样
        
        //标题就会变成黑色
        navigationController!.navigationBar.barStyle=UIBarStyle.default
        
        //设置标题字体颜色
        navigationController!.navigationBar.titleTextAttributes=[.foregroundColor:UIColor.black]
        
        //设置返回按钮为黑色
        navigationController!.navigationBar.tintColor=UIColor.black
        
        //导航栏透明
        //这里设置导航透明后，就没有上面的黑色了
        navigationController!.navigationBar.setBackgroundImage(nil, for: .default)
    }
    
    deinit {
       
        cancelTask()
    }
    
    /// Cell类型；这是一个枚举
    /// 以后其他界面也可以使用
    /// 不过等后面用到了在重构
    ///
    /// - Title: <#Title description#>
    /// - Sheet: <#Sheet description#>
    enum CellType {
        //标题
        case Title
        
        //歌单
        case Sheet
        
        //单曲
        case Song
    }
}


// MARK: - 搜索框架代理
extension DiscoveryController:PYSearchViewControllerDelegate {
    
    /// 开始搜索时调用
    /// 点击搜索，
    /// 点击历史
    /// 点击搜索提示都会调用
    ///
    /// - Parameters:
    ///   - searchViewController: <#searchViewController description#>
    ///   - searchBar: <#searchBar description#>
    ///   - searchText: <#searchText description#>
    func searchViewController(_ searchViewController: PYSearchViewController!, didSearchWith searchBar: UISearchBar!, searchText: String!) {
        print("DiscoveryController didSearchWith:\(searchText)")
        
        SwiftEventBus.post(ON_SEARCH_CLICK, sender: searchText)
    }
    
    /// 搜索输入框内容改变的时候调用
    ///
    /// - Parameters:
    ///   - searchViewController: <#searchViewController description#>
    ///   - searchBar: <#searchBar description#>
    ///   - searchText: <#searchText description#>
    func searchViewController(_ searchViewController: PYSearchViewController!, searchTextDidChange searchBar: UISearchBar!, searchText: String!) {
        print("DiscoveryController searchTextDidChange:\(searchText)")
        
        if searchText.length>0 {
            //获取搜索建议
            tryFetchSuggestion(searchText)
        }

    }
}

// MARK: - 页面统计
extension DiscoveryController {
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //使用极光分析
        //统计页面
        JANALYTICSService.startLogPageView("Discovery")
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        //页面结束
        JANALYTICSService.stopLogPageView("Discovery")
    }
}
